<?php
declare (strict_types=1);

namespace app\course\logic\live;

use app\admin\logic\system\Config as SystemConfig;
use app\common\exception\LogicException;
use app\common\logic\Attach;
use app\course\logic\base\Course;
use app\course\logic\base\CourseSection;
use app\course\model\live\CourseSectionLive as LiveSectionModel;
use app\user\logic\teacher\Teacher;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 直播课时逻辑层
 * @method group(string $string)
 */
class LiveSection extends LiveSectionModel
{

    /**
     * 创建房间成功后添加数据
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-06-19
     */
    public function createRoom($param)
    {
        // 验证搜索数据
        $this->getValidate()->scene('room')->failException()->check($param);
        $room_no = intval($param['room_no']);
        // 检查开播用户身份：讲师身份
        $teacher = app(Teacher::class)->where('user_id', static::$mid)->findOrEmpty();
        if ($teacher->isEmpty()) throw new LogicException('当前身份无开播权限');
        // 检查房间号是否正确
        $section = app(CourseSection::class)->findOrEmpty($room_no);
        if (!$section->is_last || $section->course_type != 2) throw new LogicException("未找到课时");
        // 非当前课程讲师
        $course = app(Course::class)->findOrEmpty($section->course_id);
        if ($course->teacher_id != $teacher->id) throw new LogicException("当前身份无开播权限");
        // 存在就返回，不存在就创建
        $data = $this->where('room_no', $room_no)->findOrEmpty();
        if ($data->isEmpty()) {
            $param['course_id'] = $section->course_id;
            if ($data = $this::create($param)) {
                return $data;
            } else {
                throw new LogicException("回调失败");
            }
        }
        return $data;
    }

    /**
     * 直播结束关闭房间修改数据
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-06-19
     */
    public function endRoom($param)
    {
        // 验证搜索数据
        $this->getValidate()->scene('room')->failException()->check($param);
        // 参数
        $time    = time();
        $room_no = $param['room_no'];
        // 检查讲师身份
        $teacher = app(Teacher::class)->where('user_id', static::$mid)->findOrEmpty();
        if ($teacher->isEmpty()) throw new LogicException("当前身份无停播权限");
        // 未到系统开播时间不能结束直播
        $start_time = app(CourseSection::class)->where('id', $room_no)->value('start_time');
        if ($start_time > $time) throw new LogicException("暂无法结束");
        // 添加停播时间
        $data = $this->where('room_no', $room_no)->findOrFail();
        $data->close_time = $time;
        if (!$data->save()) throw new LogicException("回调失败");

        return $data;
    }

    public function addHour($course_id, $pid, $param)
    {
        // 验证数据
        $this->getValidate()->scene('add_hour')->failException()->check($param);

        // 课程设置的目录层级与当前层级一致，方为课时
        $course    = app(Course::class)->findOrFail($course_id);
        $sec_level = $course->section_level;

        if ($pid == 0) {
            if ($sec_level != 1) {
                throw new LogicException("课时层级错误");
            }
            $level = 1;
        } else {
            $data = app(CourseSection::class)->findOrFail($pid);
            if ($course_id != $data->course_id) {
                throw new LogicException("课程与课时不匹配");
            }
            $level = $data->level + 1;
            if ($level != $sec_level) {
                throw new LogicException("课时层级错误");
            }
        }

        // 参数
        $param['pid']         = $pid;
        $param['status']      = 1;
        $param['course_id']   = $course_id;
        $param['course_type'] = $course->course_type;
        $param['is_last']     = 1;
        $param['level']       = $level;

        // 创建课时
        $create = CourseSection::create($param);
        if ($create->isEmpty()) {
            throw new LogicException("添加失败");
        }

        return $create;
    }

    public function editHour($course_id, $sid, $param)
    {
        $data = app(CourseSection::class)->with(['course_base_info'])->findOrFail($sid);
        if ($course_id != $data->course_id) {
            throw new LogicException("课程与课时不匹配");
        }

        // 开播信息
        $live_data = $this->where('room_no', $sid)->findOrEmpty();

        $time   = time();
        $is_end = $data->end_time < $time || (!$live_data->isEmpty() && $live_data->close_time < $time);

        if ($is_end) {
            // 直播结束，只能修改回放
            $playback_id = $param['playback_id'] ?? 0;

            if ($playback_id) {
                if ($live_data->isEmpty()) {
                    $re = $this::create([
                        'room_no'     => $sid,
                        'attach_id'   => $playback_id,
                        'course_id'   => $course_id,
                        'create_time' => $time,
                        'close_time'  => $time,
                    ]);
                    if ($re->isEmpty()) {
                        throw new LogicException("编辑失败");
                    }
                } else {
                    $live_data->attach_id = $playback_id;
                    if (!$live_data->save()) {
                        throw new LogicException("编辑失败");
                    }
                }
            }
        } else {
            // 参数
            // $data->status       = app(CourseSection::class)->getHourAuditStatus(request()->mid);
            $data->title      = $param['title'] ?? $data->title;
            $data->start_time = $param['start_time'] ?? $data->start_time;
            $data->end_time   = $param['end_time'] ?? $data->end_time;
            $data->price      = $param['price'] ?? $data->price;
            $data->class_hour = $param['class_hour'] ?? $data->class_hour;
        }

        if (!$data->save()) {
            throw new LogicException("编辑失败");
        }

        return $data;
    }

    public function getCallbackUrl($room_no)
    {
        $live_data = $this->findOrEmpty($room_no);
        $url       = null;
        if (!$live_data->isEmpty()) {
            if ($live_data->attach_id) {
                $attach = app(Attach::class)->findOrEmpty($live_data->attach_id);
                $url    = $attach->isEmpty() ? null : ($attach->fileurl ?: null);
            // } else if ($live_data->live_type == 2 || $live_data->live_type == 3) {
            //     $url = $live_data->cc_replay_id;
            }

        }

        return $url;
    }

    /**
     * 直播带课数据
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-12-03
     *
     * @param  [type]                      $param [description]
     * @return mixed [type]                             [description]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function courseDatas($param)
    {
        // 验证搜索数据
        $this->getValidate()->scene('course_datas')->failException()->check($param);

        $section_id   = $param['section_id'];
        $section_data = app(CourseSection::class)->findOrFail($section_id);

        // 带货课程
        return app(Course::class)
            ->where('id', 'IN', $section_data->course_ids)
            ->field('id,title,course_type,price,cover,scribing_price')
            ->with(['cover_url'])
            ->select()
            ->append(['course_type_text']);
    }

    /**
     * 检测直播服务商
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2021/11/15
     *
     * @return int
     */
    public function checkLiveProvider()
    {
        $config = SystemConfig::get('live_provider_used', ['provider_id' => 0]);

        $liveProviderId = intval($config['provider_id']);

        if ($liveProviderId === 0) throw new LogicException('请先配置直播服务商信息并启用');

        return $liveProviderId;
    }
}
